package com.woniu.order.service.impl;

import com.alibaba.nacos.common.model.core.IResultCode;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.entity.PageResult;
import com.woniu.entity.Result;
import com.woniu.entity.ResultCode;
import com.woniu.order.entity.dto.QueryServiceOrderDto;
import com.woniu.order.entity.vo.QueryServiceOrderVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.entity.PageResult;
import com.woniu.order.entity.OrderEndQuery;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.entity.PageResult;
import com.woniu.order.controller.AlipayController;
import com.woniu.order.entity.OrderEndQuery;
import com.woniu.order.entity.dto.DisplayChooseProductByUserDTO;
import com.woniu.order.mapper.OrderItemMapper;
import com.woniu.order.entity.vo.StatisticsOrderInfoVo;
import com.woniu.order.pojo.Order;
import com.woniu.order.mapper.OrderMapper;
import com.woniu.order.pojo.OrderItem;
import com.woniu.order.service.IOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Autowired;
import org.bouncycastle.asn1.esf.OtherRevRefs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Autowired;
import com.woniu.pay.entity.PayObject;
import com.woniu.pay.feign.AlipayFeignClient;
import com.woniu.product.feign.ProductFeignClient;
import com.woniu.product.pojo.Product;
import com.woniu.user.entity.feign.PickAddressFeignClient;
import com.woniu.user.entity.feign.UserInfoFeignClient;
import com.woniu.user.pojo.PickAddress;
import com.woniu.util.IdWorker;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.util.StringUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author LiFangyu
 * @since 2023-02-15
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {


    @Autowired
    private ProductFeignClient productFeignClient;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private PickAddressFeignClient pickAddressFeignClient;
    @Resource
    private OrderMapper orderMapper;

    @Resource
    private OrderItemMapper orderItemMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Resource
    private AlipayController alipayController;
    @Resource
    private UserInfoFeignClient userInfoFeignClient;

    @Override
    public Result queryServiceOrder(Integer currentPage, Integer currentSize,QueryServiceOrderDto queryServiceOrderDto) {
        IPage<QueryServiceOrderVo> page = new Page<>(currentPage,currentSize);
        IPage<QueryServiceOrderVo> result =orderMapper.selectPageServiceOrderVo(page,queryServiceOrderDto);
        PageResult<QueryServiceOrderVo> pageResult = new PageResult<>(result.getTotal(),result.getRecords());
        if (pageResult != null){
            return Result.ok(pageResult);
        }
        return Result.error(ResultCode.RESULE_DATA_NONE.getCode(),ResultCode.RESULE_DATA_NONE.getMessage());
    }

    @Override
    public Result shopQueryOrder(String shopId, String no) {
        Order order = orderMapper.shopQueryOrder(shopId,no);
        if (order != null){
            return Result.ok(order);
        }
        return Result.error(ResultCode.RESULE_DATA_NONE.getCode(),ResultCode.RESULE_DATA_NONE.getMessage());
    }


    @Override
    public PageResult<Order> queryOrderThroughBackEnd(Integer currentPage, Integer pageSize, OrderEndQuery orderEndQuery) {
        IPage<Order> page = new Page(currentPage,pageSize);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<Order>();
        wrapper.eq(!StringUtils.isEmpty(orderEndQuery.getServiceId()),Order::getServiceId,orderEndQuery.getServiceId())
                .eq(!StringUtils.isEmpty(orderEndQuery.getProductId()),Order::getProductId,orderEndQuery.getProductId())
                .eq(!StringUtils.isEmpty(orderEndQuery.getStatus()),Order::getStatus,orderEndQuery.getStatus())
                .gt(!StringUtils.isEmpty(orderEndQuery.getStartTime()),Order::getCreatedTime,orderEndQuery.getStartTime())
                .lt(!StringUtils.isEmpty(orderEndQuery.getEndTime()),Order::getCreatedTime,orderEndQuery.getEndTime());

        IPage<Order> selectPage = orderMapper.selectPage(page, wrapper);
        return new PageResult<Order>(selectPage.getTotal(),selectPage.getRecords());
    }


    @Override
    public String displayChooseProductsByUser(DisplayChooseProductByUserDTO displayChooseProductByUserDTO, String username) throws Exception {
        BigDecimal total = new BigDecimal(0);
        //1.判断商品库存
        for (String id : displayChooseProductByUserDTO.getIds()) {
            Product product = productFeignClient.selectProductById(id).getData();
            OrderItem orderItem = (OrderItem) redisTemplate.boundHashOps("cart_" + username).get(id);
            if (product.getStock() < orderItem.getProductQuantity()){
                throw new Exception("库存不够");
            }
            //计算总金额,total.add()累加，还需要赋值
            total = total.add(orderItem.getProductPrice().multiply(new BigDecimal(orderItem.getProductQuantity())));
        }
        //2.查询收货地址
        PickAddress pickAddress = pickAddressFeignClient.queryById(displayChooseProductByUserDTO.getReceiverId()).getData();
        //3.创建并保存order对象
        Order order = new Order();
        IdWorker idWorker = new IdWorker(0,1);
        long orderNo = idWorker.nextId();
        //4.创建并保存orderItem对象
        order.setNo(orderNo + "");//订单编号,雪花算法IDwork
        order.setUserId(userInfoFeignClient.getByUsername(username).getData().getId());
        order.setStatus(0);
        order.setCreatedTime(new Date());
        order.setUserName(username);
        order.setTotalAmount(total);
        order.setPayAmount(total);
        order.setReceiverName(pickAddress.getReceiverName());
        order.setReceiverCity(pickAddress.getReceiverCity());
        order.setReceiverDetailAddress(pickAddress.getReceiverDetailAddress());
        order.setReceiverPhone(pickAddress.getReceiverPhone());
        order.setReceiverProvince(pickAddress.getReceiverProvince());
        order.setReceiverPostCode(pickAddress.getReceiverPostCode());
        order.setReceiverRegion(pickAddress.getReceiverRegion());
        //保存到数据库
        orderMapper.insert(order);
        //创建并保存orderItem
        for (String id : displayChooseProductByUserDTO.getIds()) {
            OrderItem orderItem = (OrderItem) redisTemplate.boundHashOps("cart_" + username).get(id);
            orderItem.setOrderId(order.getId());
            orderItem.setOrderNo(order.getNo());
            //保存到数据库
            orderItemMapper.insert(orderItem);
            //5.删除对应的购物车中的商品,添加完后删除
            //redisTemplate.boundHashOps("cart_" + username).delete(id);
        }
        //6.预扣库存,调用product微服务
        for (String id : displayChooseProductByUserDTO.getIds()) {
            Product product = productFeignClient.selectProductById(id).getData();
            OrderItem orderItem = (OrderItem) redisTemplate.boundHashOps("cart_" + username).get(id);
            assert orderItem != null;
            productFeignClient.updateStock(id,orderItem.getProductQuantity());
        }
        for (String id : displayChooseProductByUserDTO.getIds()) {
            OrderItem orderItem = (OrderItem) redisTemplate.boundHashOps("cart_" + username).get(id);
            orderItem.setOrderId(order.getId());
            orderItem.setOrderNo(order.getNo());
            //保存到数据库
            orderItemMapper.insert(orderItem);
            //5.删除对应的购物车中的商品,添加完后删除
            redisTemplate.boundHashOps("cart_" + username).delete(id);
        }
        //7.将订单信息发送到mq的延时队列
        rabbitTemplate.convertAndSend("ttlOrderExchange", "ttl_order", order.getNo());
        //8.调用支付方法
        PayObject payObject = new PayObject();
        payObject.setOutTradeNo(order.getNo());
        payObject.setTotalAmount(order.getTotalAmount() + "");
        String form = (String) alipayController.toPay(payObject).getData();
        System.out.println(form);
        return form;
    }

    @Override
    public Order getbyNo(String out_trade_no) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getNo,out_trade_no);
        return orderMapper.selectOne(wrapper);
    }

    @Override
    public List<Order> selectOrderListByUsername(String username) {
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name",username);
        return orderMapper.selectList(wrapper);
    }

    @Override
    public Order selectOrderByOrderNOAndUsername(String orderNo, String username) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getNo,orderNo);
        wrapper.eq(Order::getUserName,username);
        return orderMapper.selectOne(wrapper);
    }

    @Override
    public Result queryServiceStatistics(Integer currentPage, Integer currentSize, QueryServiceOrderDto queryServiceOrderDto) {
        IPage<StatisticsOrderInfoVo> page = new Page<>(currentPage,currentSize);
        IPage<StatisticsOrderInfoVo> result =orderMapper.queryServiceStatistics(page,queryServiceOrderDto);
        PageResult<StatisticsOrderInfoVo> pageResult = new PageResult<>(result.getTotal(),result.getRecords());
        if (pageResult != null){
            return Result.ok(pageResult);
        }
        return Result.error(ResultCode.RESULE_DATA_NONE.getCode(),ResultCode.RESULE_DATA_NONE.getMessage());
    }


}
